package cn.lili.modules.promotion.manage;

import cn.lili.common.utils.RandomSelection;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.promotion.entity.dos.BlindboxPrizePaper;
import cn.lili.modules.promotion.entity.dos.BlindboxRule;
import cn.lili.modules.promotion.entity.dos.BlindboxRuleOrder;
import cn.lili.modules.promotion.entity.dos.LiBlindboxRuleGoods;
import cn.lili.modules.promotion.entity.dto.CallbackBlindboxDTO;
import cn.lili.modules.promotion.service.BlindboxPrizePaperService;
import cn.lili.modules.promotion.service.BlindboxRuleOrderService;
import cn.lili.modules.promotion.service.LiBlindboxRuleGoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @Author xiangqian
 * @Date 2023/10/5 14:32
 */
@Component
public class BlindboxCountManage {

    @Resource
    private BlindboxPrizePaperService blindboxPrizePaperService;
    @Resource
    private LiBlindboxRuleGoodsService blindboxRuleGoodsService;
    @Resource
    private BlindboxRuleOrderService blindboxRuleOrderService;

    /**
     * 分配奖卷
     *
     * @param userId       用户ID
     * @param goodsId      商品ID
     * @param blindboxRule 规则
     * @param countBuyNum  总统计次数
     */
    public void dominatePaer(String userId, String goodsId, BlindboxRule blindboxRule, Integer countBuyNum) {
        //查询奖卷
        //List<BlindboxPrizePaper> blindboxPrizePaperList = blindboxPrizePaperService.getBlindboxPrizePaper(userId, goodsId);

        //计算可分配奖卷次数
        //Integer tempNumber = countBuyNum / blindboxRule.getRuleBuyNum();
        //计算需要分配奖卷次数
        //Integer canNumber = tempNumber - blindboxPrizePaperList.size();
        if (countBuyNum < 0) {
            return;
        }
        //生成奖卷
        for (int i = 0; i < countBuyNum; i++) {
            blindboxPrizePaperService.insertPrizepaperRead(userId, goodsId, blindboxRule);
        }
    }

    /**
     * 新增奖品订单
     *
     * @param callbackBlindboxDTO 下单信息
     * @param blindboxRule        规则信息
     */
    public void blindboxRuleOrder(CallbackBlindboxDTO callbackBlindboxDTO, BlindboxRule blindboxRule) {
        //根据规则ID查询奖品
        List<LiBlindboxRuleGoods> liBlindboxRuleGoodsByRuleId = blindboxRuleGoodsService.getLiBlindboxRuleGoodsByRuleId(blindboxRule.getId());

        //新增奖品订单
        for (int i = 0; i < callbackBlindboxDTO.getOrderNumber(); i++) {
            LiBlindboxRuleGoods liBlindboxRuleGoods = pickOne(liBlindboxRuleGoodsByRuleId);
            if(liBlindboxRuleGoods!=null){
                BlindboxRuleOrder blindboxRuleOrder = new BlindboxRuleOrder();
                blindboxRuleOrder.setRuleId(blindboxRule.getId());
                blindboxRuleOrder.setRuleGoodsName(liBlindboxRuleGoods.getRuleGoodsName());
                blindboxRuleOrder.setRuleGoodsImage(liBlindboxRuleGoods.getRuleGoodsImage());
                blindboxRuleOrder.setOrderSn(callbackBlindboxDTO.getOrderSn());
                blindboxRuleOrder.setOrderItemSn(callbackBlindboxDTO.getOrderItemSn());
                blindboxRuleOrderService.save(blindboxRuleOrder);
            }
        }

        //更新规则
        blindboxRuleGoodsService.updateBatchById(liBlindboxRuleGoodsByRuleId);
    }

    /**
     * 检查是否达到开奖条件
     *
     * @param countBuyNum  总统计购买次数
     * @param blindboxRule 规则
     */
    public Boolean checkPrizeCondition(BlindboxRule blindboxRule, Integer countBuyNum) {
        if (countBuyNum >= blindboxRule.getRuleNum()) {
            return true;
        }
        return false;
    }

    /**
     * 根据商品ID查询该商品所有奖卷
     *
     * @param goodsId 商品ID
     */
    public List<BlindboxPrizePaper> getBlindboxPrizePaper(String goodsId) {
        List<BlindboxPrizePaper> blindboxPrizePaper = blindboxPrizePaperService.getBlindboxPrizePaper(null, goodsId);
        return blindboxPrizePaper;
    }

    /**
     * 生成开奖蒋卷
     *
     * @param blindboxPrizePaper 所有奖卷
     */
    public String generatePrize(List<BlindboxPrizePaper> blindboxPrizePaper) {
        List<BlindboxPrizePaper> prizePaperList = null;
        //排除黑名单用户ID
        /*if(StringUtils.isNotEmpty(notUserids)){
            prizePaperList = blindboxPrizePaper.stream().filter(paper -> !containsId(notUserids.split(","), paper.getUserId())).toList();
        }*/
        if (prizePaperList == null) {
            prizePaperList = blindboxPrizePaper;
        }

        //计算中奖CODE
        List<String> codeList = Optional.ofNullable(prizePaperList).orElse(new ArrayList<>()).stream().map(BlindboxPrizePaper::getCode).collect(Collectors.toList());
        String code = RandomSelection.getRandomElement(codeList);
        return code;
    }

    private static boolean containsId(String[] ids, String targetId) {
        for (String id : ids) {
            if (id.equals(targetId)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 生成奖品
     *
     * @param goodsList 所有奖品
     */
    public synchronized LiBlindboxRuleGoods pickOne(List<LiBlindboxRuleGoods> goodsList) {
        //生成开奖奖品
        List<LiBlindboxRuleGoods> validGoodsList = new ArrayList<>();
        for (LiBlindboxRuleGoods goods : goodsList) {
            if (goods.getRuleGoodsNumber() - goods.getRuleGoodsOffNumber() > 0) {
                for(int i =0;i<goods.getRuleGoodsNumber() - goods.getRuleGoodsOffNumber();i++){
                    validGoodsList.add(goods);
                }
            }
        }

        if (validGoodsList.isEmpty()) {
            return null;
        }
        int index = ThreadLocalRandom.current().nextInt(validGoodsList.size());
        LiBlindboxRuleGoods result = validGoodsList.get(index);

        //已开奖品数量 增加
        for (LiBlindboxRuleGoods liBlindboxRuleGoods : goodsList) {
            if (liBlindboxRuleGoods.getId().equals(result.getId())) {
                liBlindboxRuleGoods.setRuleGoodsOffNumber(liBlindboxRuleGoods.getRuleGoodsOffNumber() + 1);
            }
        }
        return result;
    }
}
